<?php

namespace app\applet\controller\user;

use app\applet\model\user\User;
use app\common\controller\Applet;
use app\common\model\work_area\WorkAreaUser;
use app\common\service\RedisQuantity;
use app\common\service\we_chat\AppletService;
use hg\apidoc\annotation as Apidoc;
use thans\jwt\facade\JWTAuth;

/**
 * @Apidoc\Title("登录相关")
 */
class Login extends Applet
{
    //中间件不验证的方法
    protected $middleware = [
        'app\\middleware\\Applet' => [
            'except' => ['getToken', 'accountLogin']
        ]
    ];


    /**
     * @Apidoc\Title("小程序登录获取Token")
     * @Apidoc\Url("/applet/user.Login/getToken")
     * @Apidoc\Method("POST")
     * @Apidoc\Param("code",type="string",require=true, desc="小程序code")
     * @Apidoc\Returned("data", type="object", desc="对象信息",
     *    @Apidoc\Returned("token", type="string", desc="秘钥"),
     *    @Apidoc\Returned("ttl", type="int", desc="过期时间")
     * )
     */
    public function getToken()
    {
        try {
            $param = $this->request->param();
            Validate([
                'code|小程序code' => 'require',
            ])->check($param);
            $openid = AppletService::getOpenid($param['code']);
            $ip = request()->ip();
            $time = time();
            $info = User::where(['openid' => $openid['openid']])->find();
            $user = new User;
            //注册
            if (empty($info)) {
                //注册
                $user->save([
                    'openid' => $openid['openid'],
                    'session_key' => $openid['session_key'],
                    'create_time' => $time,
                    'login_time' => $time,
                    'login_num' => 1,
                    'login_ip' => $ip,
                ]);
                $work_area_user_id = 0;
                $user_id = $user->id;
            } else {
                //修改
                $user->where(['id' => $info->id])->update([
                    'login_num' => ['inc', 1],
                    'login_time' => time(),
                    'session_key' => $openid['session_key'],
                    'login_ip' => $ip,
                ]);
                $work_area_user_id = $info->work_area_user_id ?? 0;
                $user_id = $info->id;
            }
            $token = JWTAuth::builder([
                'user_id' => $user_id,
                'session_key' => $openid['session_key'],
                'openid' => $openid['openid'],
                'work_area_user_id' => $work_area_user_id,
                'type' => 'applet',
            ]);
        } catch (\Exception $e) {
            // 验证失败 输出错误信息
            return $this->ajax(0, $e->getMessage());

        }
        return $this->ajax(1, "登陆成功", [
            'token' => 'bearer ' . $token,
            'ttl' => 7000,
        ]);
    }

    /**
     * @Apidoc\Title("账号登录获取Token")
     * @Apidoc\Url("/applet/user.Login/accountLogin")
     * @Apidoc\Method("POST")
     * @Apidoc\Param("account",type="string",require=true, desc="账号")
     * @Apidoc\Param("password",type="string",require=true, desc="密码")
     * @Apidoc\Returned("data", type="object", desc="对象信息",
     *    @Apidoc\Returned("token", type="string", desc="秘钥"),
     *    @Apidoc\Returned("ttl", type="int", desc="过期时间")
     * )
     */
    public function accountLogin()
    {
        try {
            $param = $this->request->param();
            $result = JWTAuth::auth();
            $user_id = $result['user_id'];
            Validate([
                'account|账号' => 'require',
                'password|密码' => 'require',
            ])->check($param);
            //工区账号
            $work_area_user = WorkAreaUser::where(['account' => $param['account']])->find();
            if (empty($work_area_user)) throw new \Exception('账号不存在');
            $password = md5(md5($param['password']) . "admin");
            if ($password != $work_area_user->password) throw new \Exception('密码错误');
            //检查工区有没被绑定到小程序用户身上
            $work_area_user_id = User::where(['work_area_user_id' => $work_area_user->id])->value('work_area_user_id');
            //工区没有绑定，绑定到首次登录用户上
            if (empty($work_area_user_id)) {
                $info = User::where(['id' => $user_id])->field(['id', 'nickname', 'phone', 'head', 'work_area_user_id'])->find();
                if ($info->work_area_user_id == 0) {
                    User::where(['id' => $user_id])->update(['work_area_user_id' => $work_area_user->id]);
                }
                $work_area_user_id = $work_area_user->id;
            }
            $token = JWTAuth::builder([
                'user_id' => $user_id,
                'type' => 'applet',
                'work_area_user_id' => $work_area_user_id
            ]);
            if (!RedisQuantity::FrequencyLimit(md5(request()->controller() . request()->action() . $user_id), 2)) {
                throw new \Exception('请求频繁,稍后再试');
            }
        } catch (\Exception $e) {
            // 验证失败 输出错误信息
            return $this->ajax(0, $e->getMessage());
        }
        return $this->ajax(1, "登陆成功", [
            'token' => 'bearer ' . $token,
            'ttl' => 7000,
            'type' => $work_area_user->type,
            'work_area_id' => $work_area_user_id,
        ]);
    }
}